package com.alibaba.citrus.ots.sales.plan.facade.service.statistics;

import com.alibaba.acm.shaded.com.google.common.collect.Lists;
import com.alibaba.acm.shaded.com.google.common.collect.Maps;
import com.alibaba.citrus.ots.common.annotation.FacadeInvoker;
import com.alibaba.citrus.ots.common.exception.FacadeException;
import com.alibaba.citrus.ots.sales.plan.api.salesplan.report.SalesPlanReportQueryService;
import com.alibaba.citrus.ots.sales.plan.api.statistics.SalesPlanScItemStatQueryService;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.DimensionDTO;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.PageQueryDepartmentTaskCountRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.PageQueryPlanScItemStatRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.QueryPlanScItemStatRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.QuerySalesPlanRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.SalesPlanReportQueryRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.SalesPlanReportRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.request.SalesPlanScItemStatSubTotalRequest;
import com.alibaba.citrus.ots.sales.plan.dto.api.response.DepartmentResponse;
import com.alibaba.citrus.ots.sales.plan.dto.api.response.SalesPlanScItemStatSubTotalResponse;
import com.alibaba.citrus.ots.sales.plan.facade.service.SalesPlanCommonService;
import com.alibaba.citrus.ots.sales.plan.model.SalesPlanReportAuditStatusEnum;
import com.alibaba.citrus.ots.sales.plan.model.SalesPlanReportStatusEnum;
import com.alibaba.citrus.ots.sales.plan.model.enums.SalesPlanModelEnum;
import com.alibaba.citrus.ots.sales.plan.model.enums.SalesStatBizTypeEnum;
import com.alibaba.citrus.ots.sales.plan.model.enums.StatPoolTypeEnum;
import com.alibaba.citrus.ots.sales.plan.repository.SalesPlanRepository;
import com.alibaba.citrus.ots.sales.plan.repository.SalesPlanScItemStatRepository;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanReportSDO;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanSDO;
import com.alibaba.citrus.ots.sales.plan.sdo.SalesPlanStatScItemSDO;
import com.alibaba.cz.base.tool.StringUtil;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.message.ErrorMessage;
import com.alibaba.cz.base.tool.page.PageResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.model.dto.*;
import com.epoch.app.bcots.sales_plan.planscitem.model.PlanScItem;
import com.epoch.app.bcots.sales_plan.planscitem.service.PlanScItemService;
import com.epoch.app.bcots.service.BaseDataService;
import com.epoch.app.bcots.service.UnifiedInventoryService;
import com.epoch.app.otsunifiedinventory.model.dto.GetCompanyInventoryRequest;
import com.epoch.app.otsunifiedinventory.model.dto.WarehouseInventory;
import com.epoch.app.otsunifiedinventory.service.OtsUnifiedInventoryService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author yuhailin
 * @description:
 * @date 2021-09-27 10:37
 */
@Component
public class SalesPlanScItemStatQueryServiceImpl implements SalesPlanScItemStatQueryService {

    private final Log log = Log.getLogger(SalesPlanScItemStatQueryServiceImpl.class);

    @Resource
    private SalesPlanScItemStatRepository salesPlanScItemStatRepository;

    @Resource
    private SalesPlanCommonService salesPlanCommonService;

    @Resource
    private SalesPlanReportQueryService salesPlanReportQueryService;

    @Resource
    private BaseDataService baseDataService;

    @Resource
    private UnifiedInventoryService unifiedInventoryService;

    @Resource
    private OtsUnifiedInventoryService otsUnifiedInventoryService;

    @Resource
    private SalesPlanRepository salesPlanRepository;

    @Resource
    private PlanScItemService planScItemService;

    @FacadeInvoker
    @Override
    public Result<PageResult<List<SalesPlanStatScItemSDO>>> pageQueryPlanScItemList(PageQueryPlanScItemStatRequest pageQueryPlanScItemStatRequest) {
        pageQueryPlanScItemStatRequestConverter(pageQueryPlanScItemStatRequest);
        PageResult<List<SalesPlanStatScItemSDO>> listPageResult = salesPlanScItemStatRepository.pageQueryPlanScItemList(pageQueryPlanScItemStatRequest);
        listPageResultConverter(listPageResult, pageQueryPlanScItemStatRequest);
        // 只有货品维度和类目维度才查询库存

        Integer poolType = pageQueryPlanScItemStatRequest.getPoolType();
        if (StatPoolTypeEnum.CATEGORY.getPoolType().equals(poolType) || StatPoolTypeEnum.SC_ITEM.getPoolType().equals(poolType)) {
            refreshStock(listPageResult, pageQueryPlanScItemStatRequest);
        }
        return Result.success(listPageResult);
    }

    /**
     * 填充库存
     *
     * @param listPageResult
     * @param pageQueryPlanScItemStatRequest
     */
    private void refreshStock(PageResult<List<SalesPlanStatScItemSDO>> listPageResult, PageQueryPlanScItemStatRequest pageQueryPlanScItemStatRequest) {
        List<String> scItemIdList = new ArrayList<>();
        // 货品维度查询库存，类目维度查询货品，在查库存
        List<SalesPlanStatScItemSDO> listPageResultContent = listPageResult.getContent();
        if (CollectionUtils.isEmpty(listPageResultContent)) {
            return;
        }
        // 根据planId查询分子公司编码
        String planId = pageQueryPlanScItemStatRequest.getPlanId();
        QuerySalesPlanRequest querySalesPlanRequest = new QuerySalesPlanRequest();
        querySalesPlanRequest.setId(planId);
        SalesPlanSDO salesPlanSDO = null;
        try {
            salesPlanSDO = salesPlanRepository.load(querySalesPlanRequest);
        } catch (Exception e) {
            return;
        }
        if (Objects.isNull(salesPlanSDO)) {
            return;
        }
        String orgBusinessUnitCode = salesPlanSDO.getOrgBusinessUnitCode();
        Integer poolType = pageQueryPlanScItemStatRequest.getPoolType();
        // 类目维度
        if (StatPoolTypeEnum.CATEGORY.getPoolType().equals(poolType)) {
            long start = System.currentTimeMillis();
            log.info("查询类目汇总公司库存 start:{}", start);
            // 存在货品没有类目的情况，这种货品也要查库存的
            List<SalesPlanStatScItemSDO> salesPlanStatScItemSDOListByCategory = listPageResultContent.stream()
                    .filter(salesPlanStatScItemSDO -> StringUtils.isNotBlank(salesPlanStatScItemSDO.getScItemCategoryId())).collect(Collectors.toList());
            // 根据类目id转map
            Map<String, SalesPlanStatScItemSDO> salesPlanStatScItemSDOMapByCategory = salesPlanStatScItemSDOListByCategory
                    .stream().collect(Collectors.toMap(SalesPlanStatScItemSDO::getScItemCategoryId, o -> o, (a, b) -> a));
            Map<String, String> stockMap = new HashMap<>();
            // 查找仓库
            List<String> warehouseIdList = fetchWarehouseId(orgBusinessUnitCode);
            for (String scItemCategoryId : salesPlanStatScItemSDOMapByCategory.keySet()) {
                // 根据类目查货品ids
                SearchScItemRequest searchScItemRequest = new SearchScItemRequest();
                searchScItemRequest.setPageNum(1);
                searchScItemRequest.setPageSize(2000);
                List<String> scItemCategoryIdList = Lists.newArrayList(scItemCategoryId);
                Map<String, List<String>> searchReqDTOMap = new HashMap<>();
                searchReqDTOMap.put("leafCategoryIdList", scItemCategoryIdList);
                searchScItemRequest.setSearchReqDTO(searchReqDTOMap);
                Result<List<ScItemSDO>> searchScItemResult = baseDataService.searchScItem(searchScItemRequest);
                if (null == searchScItemResult || !searchScItemResult.isSuccess()) {
                    throw new FacadeException("OTS-02-004-01-15-038");
                }
                List<ScItemSDO> scItemSDOList = searchScItemResult.getResult();
                scItemIdList = scItemSDOList.stream().map(ScItemSDO::getScItemId).collect(Collectors.toList());
                // 查询该类目维度下的所有货品的库存map，key:货品id; value:库存
                Map<String, String> stockByCategoryMap = new HashMap<>();
                try {
                    stockByCategoryMap = getStockForCompany(warehouseIdList, scItemIdList);
                } catch (Exception e) {
                    log.error("月度计划查询货品库存异常", e);
                }
                BigDecimal inventory = new BigDecimal(0);
                // stockMap求和，就是该类目下的库存总量
                if (MapUtils.isNotEmpty(stockByCategoryMap)) {
                    for (String scItemId : stockByCategoryMap.keySet()) {
                        String str = stockByCategoryMap.get(scItemId);
                        inventory = inventory.add(new BigDecimal(str));
                    }
                }
                String inventoryStr = inventory.toString();
                stockMap.put(scItemCategoryId, inventoryStr);
            }
            listPageResultContent.forEach(salesPlanStatScItemSDO -> {
                String scItemCategoryId = salesPlanStatScItemSDO.getScItemCategoryId();
                String inventory = stockMap.get(scItemCategoryId);
                salesPlanStatScItemSDO.setInventoryStr(inventory);
            });
            listPageResult.setContent(listPageResultContent);
            log.info("查询类目汇总公司库存 总耗时:{}", System.currentTimeMillis() - start);
        }
        // 货品维度
        else if (StatPoolTypeEnum.SC_ITEM.getPoolType().equals(poolType)) {
            long start = System.currentTimeMillis();
            log.info("查询货品汇总公司库存 start:{}", start);
            scItemIdList = listPageResultContent.stream().map(SalesPlanStatScItemSDO::getScItemId).collect(Collectors.toList());
            // 查询货品下的库存map，key：货品id；value：库存
            Map<String, String> stockMap = new HashMap<>();
            try {
                stockMap = getStockForCompany(fetchWarehouseId(orgBusinessUnitCode), scItemIdList);
            } catch (Exception e) {
                log.error("月度计划查询货品库存异常", e);
            }
            if (MapUtils.isNotEmpty(stockMap)) {
                Map<String, String> finalStockMap = stockMap;
                listPageResultContent.forEach(salesPlanStatScItemSDO -> {
                    String scItemId = salesPlanStatScItemSDO.getScItemId();
                    String availableQuantity = finalStockMap.get(scItemId);
                    salesPlanStatScItemSDO.setInventoryStr(availableQuantity);
                });
            }
            listPageResult.setContent(listPageResultContent);
            log.info("查询货品汇总公司库存 总耗时:{}", System.currentTimeMillis() - start);
        }
    }

    /**
     * 1、根据公司查销售组织
     * 2、根据销售组织查仓库
     * 3、根据仓库+货品id查仓库里的库存
     * 4、汇总为公司级别
     *
     * @param warehouseIdList 仓库idList
     * @param scItemIdList    货品idList
     * @return Map(货品id, 公司库存)
     */
    private Map<String, String> getStockForCompany(List<String> warehouseIdList, List<String> scItemIdList) {
        if (CollectionUtils.isEmpty(scItemIdList)) {
            return new HashMap<>();
        }
        // 3、根据仓库+货品id查仓库里的库存
        GetCompanyInventoryRequest getCompanyInventoryRequest = new GetCompanyInventoryRequest();
        getCompanyInventoryRequest.setGoodsIds(scItemIdList);
        getCompanyInventoryRequest.setWarehouseAreaIdList(warehouseIdList);
        long start = System.currentTimeMillis();
        log.info("调用公司库存接口 start:{}", start);
        Result<List<WarehouseInventory>> listWarehouseStock = otsUnifiedInventoryService.getCompanyInventory(getCompanyInventoryRequest);
        log.info("调用公司库存接口 end, 总耗时:{}", System.currentTimeMillis() - start);
        if (null == listWarehouseStock || !listWarehouseStock.isSuccess()) {
            throw new FacadeException("OTS-02-004-01-15-036");
        }
        List<WarehouseInventory> listWarehouseStockResult = listWarehouseStock.getResult();
        if (CollectionUtils.isEmpty(listWarehouseStockResult)) {
            throw new FacadeException("OTS-02-004-01-15-037");
        }
        // 根据货品id分组  每一个key代表一个货品下的所有仓库的库存量 陈慕已经汇总，一个货品只有一个库存量（聚合所有仓库）
        Map<String, List<WarehouseInventory>> listMap = listWarehouseStockResult.stream().collect(Collectors.groupingBy(WarehouseInventory::getGoodsId));
        Map<String, String> result = new HashMap<>();
        for (String scItemId : listMap.keySet()) {
            List<WarehouseInventory> warehouseInventoryList = listMap.get(scItemId);
            if (CollectionUtils.isEmpty(warehouseInventoryList)) {
                continue;
            }
            WarehouseInventory warehouseInventory = warehouseInventoryList.get(0);
            String availableQuantityFormat = warehouseInventory.getAvailableQuantityFormat();
            // 一个货品在一个仓库只有一个库存
            result.put(scItemId, availableQuantityFormat);
        }
        return result;
    }

    private List<String> fetchWarehouseId(String companyCode) {
        long start = System.currentTimeMillis();
        // 1、获取分子公司下的销售组织
        GetOrganizationSelectsRequest getOrganizationSelectsRequest = new GetOrganizationSelectsRequest();
        getOrganizationSelectsRequest.setParentId(companyCode);

        log.info("查询业务单元下的销售组织请求参数：{}", JSON.toJSONString(getOrganizationSelectsRequest));
        GetOrganizationSelectsResponse organizationSelects = baseDataService.getOrganizationSelects(getOrganizationSelectsRequest);
        log.info("查询业务单元下的销售组织返回结果：{}", JSON.toJSONString(organizationSelects));
        if (null == organizationSelects) {
            throw new FacadeException("OTS-02-004-01-15-033");
        }
        List orgResult = organizationSelects.getResult();
        if (CollectionUtils.isEmpty(orgResult)) {
            throw new FacadeException("OTS-02-004-01-15-034");
        }
        List<Map> mapList = JSONObject.parseArray(JSON.toJSONString(orgResult), Map.class);
        List<String> orgIdList = mapList.stream().map(map -> map.get("value").toString()).collect(Collectors.toList());
        // 2、根据销售组织查仓库
        SearchCargoZoneListRequest searchCargoZoneListRequest = new SearchCargoZoneListRequest();
        searchCargoZoneListRequest.setModel(3);
        searchCargoZoneListRequest.setStatus(1);
        searchCargoZoneListRequest.setSize(1000);
        searchCargoZoneListRequest.setSaleOrgIdList(orgIdList);
        log.info("查询销售组织下的仓库请求参数：{}", JSON.toJSONString(searchCargoZoneListRequest));
        SearchCargoZoneListResponse searchCargoZoneListResponse = unifiedInventoryService.searchCargoZoneList(searchCargoZoneListRequest);
        log.info("查询销售组织下的仓库返回结果：{}", JSON.toJSONString(searchCargoZoneListResponse));
        if (null == searchCargoZoneListResponse || searchCargoZoneListResponse.getTotal() <= 0
                || CollectionUtils.isEmpty(searchCargoZoneListResponse.getResult())) {
            throw new FacadeException("OTS-02-004-01-15-035");
        }
        List<WarehouseInfo> warehouseInfoList = searchCargoZoneListResponse.getResult();
        log.info("获取仓库耗时:{}", System.currentTimeMillis() - start);
        return warehouseInfoList.stream().map(WarehouseInfo::getId).collect(Collectors.toList());
    }

    private void pageQueryPlanScItemStatRequestConverter(PageQueryPlanScItemStatRequest pageQueryPlanScItemStatRequest) {
        if (StatPoolTypeEnum.ORGANIZATION.getPoolType().equals(pageQueryPlanScItemStatRequest.getPoolType()) && StringUtils.isNotBlank(pageQueryPlanScItemStatRequest.getParentId())) {
            pageQueryPlanScItemStatRequest.setBizType(null);
            pageQueryPlanScItemStatRequest.setBizId(null);
        } else {
            pageQueryPlanScItemStatRequest.setParentId(null);
            SalesPlanSDO salesPlan = salesPlanCommonService.checkSalesPlan(pageQueryPlanScItemStatRequest.getPlanId());
            DimensionDTO dimension = salesPlanCommonService.checkBizType(salesPlan, pageQueryPlanScItemStatRequest);
            pageQueryPlanScItemStatRequest.setBizType(dimension.getBizType());
            pageQueryPlanScItemStatRequest.setBizId(dimension.getBizId());
        }
    }

    private void listPageResultConverter(PageResult<List<SalesPlanStatScItemSDO>> listPageResult, PageQueryPlanScItemStatRequest request) {
        if (CollectionUtils.isEmpty(listPageResult.getContent())) {
            return;
        }
        // 暂时只要求组织汇总要求
        if (!StatPoolTypeEnum.ORGANIZATION.getPoolType().equals(request.getPoolType())) {
            return;
        }
        listPageResult.getContent().forEach(scItemSDO -> {
            scItemSDO.setOrganizationType(SalesStatBizTypeEnum.match(scItemSDO.getBizType()).getOrganizationType());
            scItemSDO.setIsAudit(false);
            //审批状态
            if (scItemSDO.getBizType() != null && StringUtil.isNotEmpty(scItemSDO.getBizId())) {
                refreshSalesPlanStatScItemSDO(scItemSDO, request);
            }
        });
        List<String> reportOrderIdList = listPageResult.getContent().stream().map(SalesPlanStatScItemSDO::getReportOrderId).filter(StringUtils::isNotBlank).collect(Collectors.toList());
        SalesPlanReportRequest reportRequest = new SalesPlanReportRequest();
        reportRequest.setReportOrderIdList(reportOrderIdList);
        reportRequest.setOperatorId(request.getOperatorId());
        Result<Map<String, Boolean>> reportMap = salesPlanReportQueryService.batchVerifyAuditPermission(reportRequest);
        if (null == reportMap || MapUtils.isEmpty(reportMap.getResult())) {
            return;
        }
        // 填充审批状态信息
        refreshSalesPlanStatScItemSDO(listPageResult.getContent(), reportMap.getResult());
    }

    @FacadeInvoker
    @Override
    public Result<PageResult<List<SalesPlanStatScItemSDO>>> queryDepartmentTaskCountList(PageQueryDepartmentTaskCountRequest queryDepartmentTaskCountRequest) {
        return Result.success(salesPlanScItemStatRepository.queryDepartmentTaskCountList(queryDepartmentTaskCountRequest));
    }

    @FacadeInvoker
    @Override
    public Result<PageResult<List<SalesPlanStatScItemSDO>>> batchQueryPlanScItemByBizId(QueryPlanScItemStatRequest queryPlanScItemStatRequest) {
        return Result.success(salesPlanScItemStatRepository.batchQueryPlanScItemByBizId(queryPlanScItemStatRequest));
    }

    @FacadeInvoker
    @Override
    public Result<List<SalesPlanStatScItemSDO>> queryPlanScItemByPlanId(QueryPlanScItemStatRequest queryPlanScItemStatRequest) {
        return Result.success(salesPlanScItemStatRepository.queryPlanScItemByPlanId(queryPlanScItemStatRequest));
    }


    @FacadeInvoker
    @Override
    public Result<SalesPlanStatScItemSDO> queryPlanScItemById(QueryPlanScItemStatRequest queryPlanScItemStatRequest) {
        return Result.success(salesPlanScItemStatRepository.getSalesPlanScItem(queryPlanScItemStatRequest));
    }

    @FacadeInvoker
    @Override
    public Result<SalesPlanStatScItemSDO> queryPlanScItemDepartmentTaskCount(PageQueryPlanScItemStatRequest pageQueryDepartmentTaskCountRequest) {
        pageQueryDepartmentTaskCountRequest.setPlanId(String.valueOf(pageQueryDepartmentTaskCountRequest.getPlanId()));
        pageQueryDepartmentTaskCountRequest.setBizType(SalesStatBizTypeEnum.SALES_DEPARTMENT.getBizType());
        PageResult<List<SalesPlanStatScItemSDO>> pageResult = salesPlanScItemStatRepository.pageQueryPlanScItemList(pageQueryDepartmentTaskCountRequest);
        List<SalesPlanStatScItemSDO> firstPageContent = pageResult.getContent();
        int totalPages = (int) pageResult.getTotalPages();
        if (totalPages >= 1) {
            IntStream.range(2, totalPages).forEach(page -> {
                pageQueryDepartmentTaskCountRequest.setPage(page);
                List<SalesPlanStatScItemSDO> salesPlanScItemStatSDOList = salesPlanScItemStatRepository.pageQueryPlanScItemList(pageQueryDepartmentTaskCountRequest).getContent();
                firstPageContent.addAll(salesPlanScItemStatSDOList);
            });
        }
        return Result.success(doCalculate(firstPageContent));

    }

    @FacadeInvoker
    @Override
    public Result<SalesPlanScItemStatSubTotalResponse> subTotalSalesPlanScItemStat(SalesPlanScItemStatSubTotalRequest salesPlanScItemStatSubTotalRequest) {
        SalesPlanSDO salesPlan = salesPlanCommonService.checkSalesPlan(salesPlanScItemStatSubTotalRequest.getPlanId());
        DimensionDTO dimension = salesPlanCommonService.checkBizType(salesPlan, salesPlanScItemStatSubTotalRequest);

        salesPlanScItemStatSubTotalRequest.setBizType(dimension.getBizType());
        salesPlanScItemStatSubTotalRequest.setBizId(dimension.getBizId());

        if (salesPlanScItemStatSubTotalRequest.getParentId() != null && salesPlanScItemStatSubTotalRequest.getPoolType() != null && salesPlanScItemStatSubTotalRequest.getPoolType().equals(StatPoolTypeEnum.ORGANIZATION.getPoolType())) {
            salesPlanScItemStatSubTotalRequest.setBizId(null);
            salesPlanScItemStatSubTotalRequest.setBizType(null);
        }
        SalesPlanStatScItemSDO planStatScItemSDO = salesPlanScItemStatRepository.subTotalSalesPlanScItemStat(salesPlanScItemStatSubTotalRequest);
        if (planStatScItemSDO == null) {
            return Result.success(null);
        }
        SalesPlanScItemStatSubTotalResponse response = new SalesPlanScItemStatSubTotalResponse();
        response.setMonthCount(planStatScItemSDO.getMonthCount());
        response.setBeforeMonthMoney(planStatScItemSDO.getBeforeMonthMoney());
        response.setMonthMoney(planStatScItemSDO.getMonthMoney());

        response.setMonthContractCount(planStatScItemSDO.getMonthContractCount());
        response.setBeforeMonthContractMoney(planStatScItemSDO.getBeforeMonthContractMoney());
        response.setMonthContractMoney(planStatScItemSDO.getMonthContractMoney());

        response.setTaskCount(planStatScItemSDO.getTaskCount());
        response.setBeforeTaskMoney(planStatScItemSDO.getBeforeTaskMoney());
        response.setTaskMoney(planStatScItemSDO.getTaskMoney());

        response.setAdjustCount(planStatScItemSDO.getAdjustCount());
        response.setBeforeAdjustMoney(planStatScItemSDO.getAdjustMoney());
        response.setAdjustMoney(planStatScItemSDO.getAdjustMoney());
        return Result.success(response);
    }

    /**
     * 分页查询回退上一级月度计划汇总数据
     *
     * @param request
     * @return
     */
    @Override
    @FacadeInvoker
    public Result<PageResult<List<SalesPlanStatScItemSDO>>> pageQueryBackPlanScItemList(PageQueryPlanScItemStatRequest request) {
        // 检查请求数据
        checkPageQueryPlanScItemStatRequest(request);
        // 获取上一级id
        SalesPlanStatScItemSDO salesPlanStatScItemSDO = fetchBackSalesPlanStatScItemSDO(request);
        if (salesPlanStatScItemSDO.getOrganizationType().equals(request.getBizType()) || StringUtils.isBlank(salesPlanStatScItemSDO.getParentId())) {
            return buildPageQueryResult(request, salesPlanStatScItemSDO);
        }
        refreshRequest(request, salesPlanStatScItemSDO.getParentId());
        return pageQueryPlanScItemList(request);
    }

    private void refreshSalesPlanStatScItemSDO(List<SalesPlanStatScItemSDO> salesPlanStatScItemSDOS, Map<String, Boolean> reportMap) {
        if (CollectionUtils.isEmpty(salesPlanStatScItemSDOS)) {
            return;
        }
        salesPlanStatScItemSDOS.forEach(scItemSDO -> {
            if (StringUtils.isBlank(scItemSDO.getReportOrderId())) {
                scItemSDO.setIsAudit(false);
                return;
            }
            scItemSDO.setIsAudit(reportMap.getOrDefault(scItemSDO.getReportOrderId(), false));
        });
    }

    private Result<PageResult<List<SalesPlanStatScItemSDO>>> buildPageQueryResult(PageQueryPlanScItemStatRequest request, SalesPlanStatScItemSDO salesPlanStatScItemSDO) {
        return Result.success(PageResult.of(Lists.newArrayList(salesPlanStatScItemSDO), 1));
    }

    private void refreshRequest(PageQueryPlanScItemStatRequest request, String parentId) {
        request.setParentId(parentId);
    }

    private void checkPageQueryPlanScItemStatRequest(PageQueryPlanScItemStatRequest request) {
        if (null == request || StringUtils.isBlank(request.getParentId())) {
            throw new FacadeException(ErrorMessage.code("OTS-02-006-00-16-001"));
        }
        if (null == request.getBizType()) {
            throw new FacadeException(ErrorMessage.code("OTS-02-006-00-16-003"));
        }
        SalesStatBizTypeEnum salesStatBizTypeEnum = SalesStatBizTypeEnum.getByOrganizationType(request.getBizType());
        if (salesStatBizTypeEnum == null) {
            throw new FacadeException(ErrorMessage.code("OTS-02-006-00-16-002"));
        }
    }

    private SalesPlanStatScItemSDO fetchBackSalesPlanStatScItemSDO(PageQueryPlanScItemStatRequest request) {
        // 获取父级汇总数据
        QueryPlanScItemStatRequest queryPlanScItemStatRequest = new QueryPlanScItemStatRequest();
        queryPlanScItemStatRequest.setBizIds(Lists.newArrayList(request.getParentId()));
        queryPlanScItemStatRequest.setPlanId(Optional.ofNullable(request.getPlanId()).map(Long::parseLong).orElse(null));
        queryPlanScItemStatRequest.setPoolType(request.getPoolType().toString());
        queryPlanScItemStatRequest.setStart(0);
        queryPlanScItemStatRequest.setLimit(1000);
        PageResult<List<SalesPlanStatScItemSDO>> pageResult = salesPlanScItemStatRepository.batchQueryPlanScItemByBizId(queryPlanScItemStatRequest);
        if (null == pageResult || CollectionUtils.isEmpty(pageResult.getContent())) {
            throw new FacadeException(ErrorMessage.code("OTS-02-006-00-16-001"));
        }
        SalesPlanStatScItemSDO salesPlanStatScItemSDO = pageResult.getContent().get(0);
        SalesStatBizTypeEnum salesStatBizTypeEnum = SalesStatBizTypeEnum.match(salesPlanStatScItemSDO.getBizType());
        if (salesStatBizTypeEnum == null) {
            throw new FacadeException(ErrorMessage.code("OTS-02-006-00-16-002"));
        }
        if (salesStatBizTypeEnum.getOrganizationType() < request.getBizType()) {
            log.warn("已超出数据权限范围，无法显示数据");
            throw new FacadeException(ErrorMessage.code("OTS-02-006-00-16-001"));
        }
        salesPlanStatScItemSDO.setOrganizationType(salesStatBizTypeEnum.getOrganizationType());
        return salesPlanStatScItemSDO;
    }

    private void refreshSalesPlanStatScItemSDO(SalesPlanStatScItemSDO scItemSDO, PageQueryPlanScItemStatRequest request) {
        String modelId = request.getPlanId();
        Integer modelType = SalesPlanModelEnum.PLAN_MODEL.getModel();
        if (Boolean.TRUE.equals(request.getIsAdjustCount())) {
            modelId = request.getAdjustId();
            modelType = SalesPlanModelEnum.ADJUST_MODEL.getModel();
        }
        SalesPlanReportQueryRequest salesPlanReportQueryRequest = new SalesPlanReportQueryRequest();
        salesPlanReportQueryRequest.setModelId(modelId);
        salesPlanReportQueryRequest.setModelType(modelType);
        salesPlanReportQueryRequest.setBizId(scItemSDO.getBizId());
        salesPlanReportQueryRequest.setBizType(scItemSDO.getBizType());
        Result<SalesPlanReportSDO> salesPlanReportSDOResult = salesPlanReportQueryService.querySalesPlanReport(salesPlanReportQueryRequest);
        if (Objects.nonNull(salesPlanReportSDOResult.getResult())) {
            scItemSDO.setAuditStatus(salesPlanReportSDOResult.getResult().getAuditStatus());
            scItemSDO.setAuditStatusName(SalesPlanReportAuditStatusEnum.of(salesPlanReportSDOResult.getResult().getAuditStatus()).getDesc());
            scItemSDO.setReportStatus(salesPlanReportSDOResult.getResult().getStatus());
            scItemSDO.setReportStatusName(SalesPlanReportStatusEnum.of(salesPlanReportSDOResult.getResult().getStatus()).getDesc());
            scItemSDO.setReportOrderId(salesPlanReportSDOResult.getResult().getId());
        } else {
            scItemSDO.setAuditStatus(SalesPlanReportAuditStatusEnum.TO_BE_REVIEW.getCode());
            scItemSDO.setAuditStatusName(SalesPlanReportAuditStatusEnum.TO_BE_REVIEW.getDesc());
            scItemSDO.setReportStatus(SalesPlanReportStatusEnum.TO_REPORT.getCode());
            scItemSDO.setReportStatusName(SalesPlanReportStatusEnum.TO_REPORT.getDesc());
        }
    }

    private SalesPlanStatScItemSDO doCalculate(List<SalesPlanStatScItemSDO> salesPlanScItemStatSDOList) {
        SalesPlanStatScItemSDO salesPlanScItemStatSDO = new SalesPlanStatScItemSDO();
        Integer taskCountSum = salesPlanScItemStatSDOList.stream().mapToInt(SalesPlanStatScItemSDO::getTaskCount).sum();
        // Integer returnCountSum = salesPlanScItemStatSDOList.stream().mapToInt(SalesPlanStatScItemSDO::getReturnCount).sum();
        Integer monthFirstReturnCountSum = salesPlanScItemStatSDOList.stream().mapToInt(SalesPlanStatScItemSDO::getMonthFirstReturnCount).sum();
        Integer monthFirstTaskCountSum = salesPlanScItemStatSDOList.stream().mapToInt(SalesPlanStatScItemSDO::getMonthFirstTaskCount).sum();
        Integer monthMiddleReturnCountSum = salesPlanScItemStatSDOList.stream().mapToInt(SalesPlanStatScItemSDO::getMonthMiddleReturnCount).sum();
        Integer monthMiddleTaskCountSum = salesPlanScItemStatSDOList.stream().mapToInt(SalesPlanStatScItemSDO::getMonthMiddleTaskCount).sum();
        Integer monthLastReturnCountSum = salesPlanScItemStatSDOList.stream().mapToInt(SalesPlanStatScItemSDO::getMonthLastReturnCount).sum();
        Integer monthLastTaskCountSum = salesPlanScItemStatSDOList.stream().mapToInt(SalesPlanStatScItemSDO::getMonthLastTaskCount).sum();
        salesPlanScItemStatSDO.setTaskCount(taskCountSum);
        // salesPlanScItemStatSDO.setReturnCount(returnCountSum);
        salesPlanScItemStatSDO.setMonthFirstReturnCount(monthFirstReturnCountSum);
        salesPlanScItemStatSDO.setMonthFirstTaskCount(monthFirstTaskCountSum);
        salesPlanScItemStatSDO.setMonthMiddleTaskCount(monthMiddleTaskCountSum);
        salesPlanScItemStatSDO.setMonthMiddleReturnCount(monthMiddleReturnCountSum);
        salesPlanScItemStatSDO.setMonthLastTaskCount(monthLastTaskCountSum);
        salesPlanScItemStatSDO.setMonthLastReturnCount(monthLastReturnCountSum);
        return salesPlanScItemStatSDO;
    }

    /**
     * 货品维度查询归属部门
     *
     * @param request
     * @return
     */
    @Override
    public Result<List<DepartmentResponse>> dimensionGoodsQueryDepartment(PageQueryPlanScItemStatRequest request) {
        //校验入参
        if (StringUtils.isBlank(request.getPlanId())) {
            throw new FacadeException("OTS-02-001-00-15-006");
        }
        if (StringUtils.isBlank(request.getScItemId())) {
            throw new FacadeException("OTS-01-005-02-15-012");
        }
        if (Objects.isNull(request.getPoolType())) {
            throw new FacadeException("OTS-02-004-01-15-002");
        }
        //根据当前：货品ID+月度计划ID+汇总类型(货品汇总)+数据维度类型(部门维度) 查询出当前货品归属哪些部门下
        Result<List<PlanScItem>> listResult = planScItemService.loadPlanScItemList(PlanScItemLoadListRequest.newPlanScItemLoadListRequestBuilder()
                .planId(request.getPlanId())
                .scItemId(request.getScItemId())
                .poolType(request.getPoolType())
                .bizType(2)
                .build());
        if (CollectionUtils.isEmpty(listResult.getResult())) {
            throw new FacadeException("OTS-05-001-10-16-022");
        }
        //获取当前货品归属于哪些部门  并每个部门分别提报量为多少（monthCount）
        Map<String, Integer> departmentKeyValuePair = listResult.getResult().stream().filter(t -> t.getBizId() != null).collect(Collectors.toMap(PlanScItem::getBizId, PlanScItem::getMonthCount, (k1, k2) -> k1));
        //取出所有的Key(BizId)进行转换成部门名称
        Set<String> departmentKey = departmentKeyValuePair.keySet();
        //List<String> departmentKey = (List<String>) strings;
        BaselineGetOrganizationByIdsAllResponse organization = baseDataService.baselineGetOrganizationByIdsAll(BaselineGetOrganizationByIdsAllRequest.builder().ids(Arrays.asList(departmentKey.toArray())).build());
        if (CollectionUtils.isEmpty(organization.getResult())) {
            throw new FacadeException("OTS-01-004-02-15-004");
        }
        //构建一个新MAP进行 名称替换掉ID 返回
        List<DepartmentResponse> departmentResponse = new ArrayList<>();
        //Map<String, Integer> valueOfDepartment = new HashMap<>();
        for (OrganizationSDO organizationSDO : organization.getResult()) {
            DepartmentResponse departmentResponse1 = new DepartmentResponse();
            departmentResponse1.setName(organizationSDO.getName());
            departmentResponse1.setMonthCount(departmentKeyValuePair.get(organizationSDO.getId()));
            departmentResponse1.setBizId(organizationSDO.getId());
            //valueOfDepartment.put(organizationSDO.getName(), departmentKeyValuePair.get(organizationSDO.getId()));
            departmentResponse.add(departmentResponse1);
        }
        return Result.success(departmentResponse);
    }
}
